/**
 * Live GPS Tracking Application
 * Track
 *
 * Copyright 2009, Ivar Clemens
 */

package nl.ivarclemens.gpstrack.track;

import nl.ivarclemens.GeoMath;

public class MemTrack extends Track {
    String name;

    int length = 75;
    int ptr = 0;

    // Track buffer
    long time[] = new long[length];
    double lat[] = new double[length];
    double lon[] = new double[length];
    double dist[] = new double[length];

    public MemTrack()
    {
        this.name = "Unnamed";
    }

    public MemTrack(String name)
    {
        this.name = name;
    }

    /**
     * Create buffers of different size and copy old contents
     */
    private void resizeBuffers(int newLength)
    {
        long newTime[] = new long[newLength];
        double newLat[] = new double[newLength];
        double newLon[] = new double[newLength];
        double newDist[] = new double[newLength];

        for(int i = 0; i < ptr && i < newLength; i++) {
            newTime[i] = time[i];
            newLat[i] = lat[i];
            newLon[i] = lon[i];
            newDist[i] = dist[i];
        }

        time = newTime;
        lat = newLat;
        lon = newLon;
        dist = newDist;

        length = newLength;
    }

    /**
     * Remaps part of the track e.g. after successful transmission
     * Only works if toPtr < froPtr
     */
    public void remapTrack(int froPtr, int toPtr)
    {
        int numValues = ptr - froPtr;
        ptr = toPtr + numValues;

        for(int i = 0; i < numValues; i++) {
            time[toPtr + i] = time[froPtr + i];
            lat[toPtr + i] = lat[froPtr + i];
            lon[toPtr + i] = lon[froPtr + i];
            dist[toPtr + i] = dist[froPtr + i];
        }
    }

    public void clear()
    {
        ptr = 0;
    }

    /**
     * Add a position to the current track/buffer
     */
    public void appendPosition(long time, double lat, double lon)
    {
        super.appendPosition(time, lat, lon);

        if(ptr == length)
            resizeBuffers(length + 50);

        this.time[ptr] = time;
        this.lat[ptr] = lat;
        this.lon[ptr] = lon;

        if(ptr == 0) {
            this.dist[ptr] = 0;
        } else {
            this.dist[ptr] = GeoMath.distance(this.lat[ptr - 1], this.lon[ptr - 1], this.lat[ptr], this.lon[ptr]);
        }

        ptr++;
    }

    public int numPoints()
    {
        return this.ptr;
    }

    public long getTime(int idx)
    {
        return this.time[idx];
    }

    public double getLat(int idx)
    {
        return this.lat[idx];
    }

    public double getLon(int idx)
    {
        return this.lon[idx];
    }

    public double getDistance(int idx)
    {
        return this.dist[idx];
    }
}
